﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using GMap.NET.WindowsPresentation;
using System.Windows.Media.Animation;

namespace ProjectorMapApp.CustomMarkers
{
    /// <summary>
    /// Interaction logic for CustomMarker.xaml
    /// </summary>
    public partial class CustomMarker
    {
        Popup Popup;
        GMapMarker Marker;
        MainWindow MainWindow;
        Image speechBubble;
        Grid grid;
        int speechBubbleMaxSizeX = 324;
        int speechBubbleMaxSizeY = 280;
        TextBlock msg;
        Storyboard popupSizeIncreaseStoryBoard = new Storyboard();
        Storyboard popupSizeDecreaseStoryBoard = new Storyboard();
        Storyboard markerClose = new Storyboard();
        bool thisMarkersPopupIsShowing = false;
        public int storyID;
        System.Windows.Forms.Timer storyBubbleLifeTimer = new System.Windows.Forms.Timer();


        public CustomMarker(MainWindow window, GMapMarker marker, string title, ImageSource categoryImage, int storiesID, bool showMessageBox)
        {
            this.storyID = storiesID;
            this.InitializeComponent();
            this.MainWindow = window;
            this.Marker = marker;
            this.Popup = new Popup();
            this.AllowDrop = false;
            this.grid = new Grid();
            this.msg = new TextBlock();
            this.speechBubble = new Image();

            this.icon.Source = categoryImage;
            this.Unloaded += new RoutedEventHandler(CustomMarker_Unloaded);
            this.Loaded += new RoutedEventHandler(CustomMarker_Loaded);
            this.SizeChanged += new SizeChangedEventHandler(CustomMarker_SizeChanged);
            this.MouseUp += new MouseButtonEventHandler(CustomMarker_MouseUp);
            this.popupSizeDecreaseStoryBoard.Completed +=new EventHandler(popupSizeDecreaseStoryBoard_Completed);
            this.popupSizeIncreaseStoryBoard.Completed +=new EventHandler(popupSizeIncreaseStoryBoard_Completed);
            this.markerClose.Completed += new EventHandler(markerClose_Completed);
            this.MouseEnter += new MouseEventHandler(MarkerControl_MouseEnter);
            this.MouseLeave += new MouseEventHandler(MarkerControl_MouseLeave);

            //Popup.Placement = PlacementMode.Mouse;
            Popup.AllowsTransparency = true;
            Popup.PlacementTarget = this;
            Popup.Name = "Popup";
            Popup.Placement = PlacementMode.Top;
            Popup.HorizontalOffset = speechBubbleMaxSizeX/5 -30;
            Popup.VerticalOffset = speechBubbleMaxSizeY / 5 +5;
            NameScope.SetNameScope(Popup, new NameScope());
            Popup.RegisterName(Popup.Name, Popup);


            //Popup.Background = Brushes.Transparent;
            //Popup.WindowStyle = WindowStyle.None;
            //Popup.ShowInTaskbar = false;
            //Popup.Topmost = true;

            string storyText = "";
            ///cuts the string short to fit in bubble if it is too big
            if (title.Length > 170)
            {
                //Console.WriteLine(title);
                storyText = title.Substring(0, 170) + " ..";
            }
            else
            {
                storyText = title;
            }
            

            //txtBox1.IsReadOnly = true;
            //txtBox1.Padding = new Thickness(5);
            //txtBox1.BorderBrush = Brushes.Black;
            //txtBox1.BorderThickness = new Thickness(2);
            //txtBox1.Background = Brushes.Transparent;
            //txtBox1.FontSize = 18;
            //txtBox1.Text = title;
            //txtBox1.MaxWidth = 400;
            //txtBox1.MaxLines = 6;
            //txtBox1.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
            //txtBox1.TextWrapping = TextWrapping.Wrap;

            msg.Padding = new Thickness(20);
            //msg.VerticalAlignment = VerticalAlignment.Center;
            //msg.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            msg.MaxWidth = speechBubbleMaxSizeX;
            msg.MaxHeight = speechBubbleMaxSizeY;

            msg.TextWrapping = TextWrapping.Wrap;
            msg.Text = storyText;
            msg.FontFamily = new FontFamily("Lucida Sans Unicode");

            
            msg.FontSize = 18;
            msg.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            msg.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            
                
            speechBubble.Source = new BitmapImage(new Uri("/ProjectorMapApp;component/Images/speechBubble2.png", UriKind.Relative));
            //speechBubble.Opacity = 0.8;
            //speechBubble.Source = GetImage(Properties.Resources.);    
            //speechBubble.IsHitTestVisible = false;
            //speechBubble.Height = speechBubbleMaxSizeY;
            //speechBubble.Width = speechBubbleMaxSizeX;
            speechBubble.Stretch = Stretch.Uniform;
            //speechBubble.Effect = new System.Windows.Media.Effects.DropShadowEffect();
                
            grid.Children.Add(speechBubble);
            //this.grid.Children.Add(msg);
            Popup.Child = grid;
            Popup.Opacity = 0.8;

            setupPopupSizeIncreaseStoryBoard();

            setupPopupSizeDecreaseStoryBoard();

            setupMarkerCloseStoryBoard();

            if (showMessageBox)
            {
                if (!this.thisMarkersPopupIsShowing)
                {
                    showMarker();
                    storyBubbleLifeTimer.Interval = 10000; //10 seconds
                    storyBubbleLifeTimer.Tick += new EventHandler(storyBubbleLifeTimer_Tick);
                    storyBubbleLifeTimer.Start();
                }
            }
        }

        //hides the text bubble
        void storyBubbleLifeTimer_Tick(object sender, EventArgs e)
        {
            if (storyBubbleLifeTimer.Enabled)
            {
                storyBubbleLifeTimer.Stop();
                storyBubbleLifeTimer.Tick -= new EventHandler(storyBubbleLifeTimer_Tick);
                hideMarker();
            }
        }

        /// <summary>
        /// shows the text bubble
        /// </summary>
        public void ShowMarkerBubble()
        {
            if (!this.thisMarkersPopupIsShowing)
            {
                showMarker();
                storyBubbleLifeTimer.Interval = 10000; //10 seconds
                storyBubbleLifeTimer.Tick += new EventHandler(storyBubbleLifeTimer_Tick);
                storyBubbleLifeTimer.Start();
            }
        }

        /// <summary>
        /// shows the text bubble
        /// </summary>
        public void HideMarkerBubble()
        {
            if (this.thisMarkersPopupIsShowing)
            {
                hideMarker();
            }
        }

        /// <summary>
        /// begins the close animation of the marker
        /// </summary>
        public void CloseAnimation()
        {
            this.markerClose.Begin();//something
        }

        void CustomMarker_Unloaded(object sender, RoutedEventArgs e)
        {
            if (this.thisMarkersPopupIsShowing)
            {
                hideMarker();
            }

            this.Unloaded -= new RoutedEventHandler(CustomMarker_Unloaded);
            this.Loaded -= new RoutedEventHandler(CustomMarker_Loaded);
            this.SizeChanged -= new SizeChangedEventHandler(CustomMarker_SizeChanged);
            this.MouseUp -= new MouseButtonEventHandler(CustomMarker_MouseUp);
            MainWindow.MainMap.MouseDown -= new MouseButtonEventHandler(MainMap_MouseDown);
            this.popupSizeDecreaseStoryBoard.Completed -= new EventHandler(popupSizeDecreaseStoryBoard_Completed);
            this.popupSizeIncreaseStoryBoard.Completed -= new EventHandler(popupSizeIncreaseStoryBoard_Completed);
            this.MouseEnter -= new MouseEventHandler(MarkerControl_MouseEnter);
            this.MouseLeave -= new MouseEventHandler(MarkerControl_MouseLeave);

            this.Marker.Shape = null;
            this.icon.Source = null;
            this.icon = null;
            this.Popup = null;
            this.msg = null;
            this.speechBubble = null;
            this.grid = null;
        }

        void MarkerControl_MouseLeave(object sender, MouseEventArgs e)
        {
            this.Marker.ZIndex -= 10000;
        }

        void MarkerControl_MouseEnter(object sender, MouseEventArgs e)
        {
            this.Marker.ZIndex += 10000;
        }

        private void setupPopupSizeIncreaseStoryBoard()
        {
            DoubleAnimation sizeAniX = new DoubleAnimation();
            sizeAniX.From = 0;
            sizeAniX.To = speechBubbleMaxSizeX;
            //sizeAniX.To = msg.Width+50;
            sizeAniX.Duration = new Duration(TimeSpan.FromSeconds(0.25));
            //sizeAniX.AutoReverse = true;
            Storyboard.SetTargetName(sizeAniX, Popup.Name);
            Storyboard.SetTargetProperty(sizeAniX, new PropertyPath(Popup.WidthProperty));

            DoubleAnimation sizeAniY = new DoubleAnimation();
            sizeAniY.From = 0;
            sizeAniY.To = speechBubbleMaxSizeY;
            //sizeAniY.To = msg.Height+50;
            sizeAniY.Duration = new Duration(TimeSpan.FromSeconds(0.25));
            Storyboard.SetTargetName(sizeAniY, Popup.Name);
            Storyboard.SetTargetProperty(sizeAniY, new PropertyPath(Popup.HeightProperty));

            this.popupSizeIncreaseStoryBoard.Children.Add(sizeAniX);
            this.popupSizeIncreaseStoryBoard.Children.Add(sizeAniY);

            //+ find a way for the marker Icon to grow  at same time!

        }

        void popupSizeIncreaseStoryBoard_Completed(object sender, EventArgs e)
        {
            if (!grid.Children.Contains(msg))
            {
                msg.Text += " ";
                grid.Children.Add(msg);
            }
        }

        private void setupPopupSizeDecreaseStoryBoard()
        {
            DoubleAnimation sizeAniX = new DoubleAnimation();
            sizeAniX.From = speechBubbleMaxSizeX;
            sizeAniX.To = 0;
            sizeAniX.Duration = new Duration(TimeSpan.FromSeconds(0.15));
            //sizeAniX.AutoReverse = true;
            Storyboard.SetTargetName(sizeAniX, Popup.Name);
            Storyboard.SetTargetProperty(sizeAniX, new PropertyPath(Popup.WidthProperty));

            DoubleAnimation sizeAniY = new DoubleAnimation();
            sizeAniY.From = speechBubbleMaxSizeY;
            sizeAniY.To = 0;
            sizeAniY.Duration = new Duration(TimeSpan.FromSeconds(0.15));
            Storyboard.SetTargetName(sizeAniY, Popup.Name);
            Storyboard.SetTargetProperty(sizeAniY, new PropertyPath(Popup.HeightProperty));

            this.popupSizeDecreaseStoryBoard.Children.Add(sizeAniX);
            this.popupSizeDecreaseStoryBoard.Children.Add(sizeAniY);
        }

        /// <summary>
        /// Convert Bitmap so its appropriate to use as ImageSource
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        private System.Windows.Media.Imaging.BitmapImage GetImage(System.Drawing.Bitmap image)
        {
            System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
            System.IO.MemoryStream mem = new System.IO.MemoryStream();
            image.Save(mem, System.Drawing.Imaging.ImageFormat.Png);
            bmp.BeginInit();
            bmp.StreamSource = mem;
            bmp.EndInit();
            return bmp;
        }

        void CustomMarker_Loaded(object sender, RoutedEventArgs e)
        {
            if (icon.Source.CanFreeze)
            {
                this.icon.Source.Freeze();
            }
        }

        void CustomMarker_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            this.Marker.Offset = new Point(-e.NewSize.Width / 2, -e.NewSize.Height);
        }

        void CustomMarker_MouseUp(object sender, MouseEventArgs e)
        {
            if (!this.thisMarkersPopupIsShowing)
            {
                showMarker();
            }
        }

        void MainMap_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.thisMarkersPopupIsShowing)
            {
                hideMarker();
            }
        }

        
        void showMarker()
        {
            this.thisMarkersPopupIsShowing = true;
            this.Marker.ZIndex += 10000;
            //MainWindow.MainMap.Position = this.Marker.Position;
            this.popupSizeIncreaseStoryBoard.Begin(Popup);
            this.popupSizeDecreaseStoryBoard.Stop();
            this.Popup.IsOpen = true;
        }

        void hideMarker()
        {
            this.Marker.ZIndex -= 10000;
            this.popupSizeIncreaseStoryBoard.Stop();

            if (grid != null && msg != null && Popup != null)
            {
                if (grid.Children.Contains(msg))
                {
                    grid.Children.Remove(msg);
                }

                this.popupSizeDecreaseStoryBoard.Begin(Popup);
            }
        }

        void popupSizeDecreaseStoryBoard_Completed(object sender, EventArgs e)
        {
            this.Popup.IsOpen = false;
            this.thisMarkersPopupIsShowing = false;
        }


        private void setupMarkerCloseStoryBoard()
        {
            DoubleAnimation sizeAniX = new DoubleAnimation();
            sizeAniX.From = 0;
            sizeAniX.To = speechBubbleMaxSizeX;
            //sizeAniX.To = msg.Width+50;
            sizeAniX.Duration = new Duration(TimeSpan.FromSeconds(0.25));
            //sizeAniX.AutoReverse = true;
            Storyboard.SetTargetName(sizeAniX, Popup.Name);
            Storyboard.SetTargetProperty(sizeAniX, new PropertyPath(Popup.WidthProperty));

            DoubleAnimation sizeAniY = new DoubleAnimation();
            sizeAniY.From = 0;
            sizeAniY.To = speechBubbleMaxSizeY;
            //sizeAniY.To = msg.Height+50;
            sizeAniY.Duration = new Duration(TimeSpan.FromSeconds(0.25));
            Storyboard.SetTargetName(sizeAniY, Popup.Name);
            Storyboard.SetTargetProperty(sizeAniY, new PropertyPath(Popup.HeightProperty));

            this.popupSizeIncreaseStoryBoard.Children.Add(sizeAniX);
            this.popupSizeIncreaseStoryBoard.Children.Add(sizeAniY);


        }

        void markerClose_Completed(object sender, EventArgs e)
        {
            this.markerClose.Completed -= new EventHandler(markerClose_Completed);
        }
    }
}